package org.one.stone.soup.grfxML.plugin.system;

import java.awt.event.MouseEvent;
import java.io.InputStream;

import org.one.stone.soup.browser.Browser;
import org.one.stone.soup.file.FileHelper;
import org.one.stone.soup.grfxML.DataActionPlugin;
import org.one.stone.soup.grfxML.DataChildren;
import org.one.stone.soup.grfxML.DataLine;
import org.one.stone.soup.grfxML.DataNode;
import org.one.stone.soup.grfxML.DataPoint;
import org.one.stone.soup.grfxML.DataProcess;
import org.one.stone.soup.grfxML.DataShape;
import org.one.stone.soup.grfxML.DataString;
import org.one.stone.soup.grfxML.GrfxMLEngine;
import org.one.stone.soup.grfxML.GrfxMLProcessor;
import org.one.stone.soup.grfxML.TagModifier;
import org.one.stone.soup.stringhelper.FileNameHelper;
import org.one.stone.soup.xml.XmlDocument;

public class NodeDropHandler implements DropHandler {

	private static int NODE_INDEX = 0;

	public NodeDropHandler()
	{
	}

	public boolean matches(String name,int x,int y) {
		if(
			FileNameHelper.getExt(name).equals("node")
		)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see org.one.stone.soup.grfxML.plugin.system.DropHandler#handle(java.lang.String)
	 */
	public boolean handle(String name,GrfxMLEngine engine,int x,int y) {

		try{
			String fileExtension = FileNameHelper.getExt(name).toLowerCase();

			if(fileExtension.equals("node"))
			{
				String data = null;
				/*if(name.indexOf("file:/")==0)
				{
					data = FileHelper.readFile(name.substring(6));
				}
				else if(name.indexOf("jar://")==0)
				{
					name = name.substring(6);
					data = ClassL;
				}
				else if(name.indexOf("http://")==-1)
				{
					data = FileHelper.readFile(name);
				}
				else
				{
					InputStream iStream = Browser.setBaseURL(name,GrfxMLEngine.key);
					data = new String(FileHelper.readFile(iStream) );
				}*/
				InputStream iStream = Browser.getInputStream(name);
				data = new String(FileHelper.readFile(iStream));

				DataNode targetNode = null;

				XmlDocument doc = engine.getAPI().getXMLParser().parseDocument(data);
				String targetName = doc.getAttributeValueByName("target");

				if(targetName!=null)
				{
					try{
						targetNode = (DataNode)engine.getAPI().getField(targetName);
					}
					catch(Exception e){}
				}

				String id = "."+NODE_INDEX;
				NODE_INDEX++;

				DataChildren target = null;

				if(targetNode==null)
				{
					targetNode = findTarget( engine.getAPI().getBase().getROOT().getChildren(),engine,new DataPoint(x,y) );
				}

				int posX = x;
				int posY = y;
				DropBuilder dropBuilder = null;

				if(targetNode==null)
				{
					targetNode = engine.getAPI().getBase().getROOT();
				}

				posX = x-targetNode.getTranslation().getPositionView().getValueX();
				posY = y-targetNode.getTranslation().getPositionView().getValueY();
				target = targetNode.getChildren();

				GrfxMLProcessor.processMouseEvent(engine,
														new MouseEvent(
															engine.getController().getComponent(),
															MouseEvent.MOUSE_MOVED,
															System.currentTimeMillis(),
															0,
															x,
															y,
															0,
															false
														),
													engine.getAPI().getMouse()
												);

				dropBuilder = findDropBuilder(targetNode);

				DataNode newNode = engine.getAPI().buildPrototype(data,id,posX,posY,target,false);
				DataString source = new DataString(name);
				source.setId("source",this);
				newNode.getData().add(source,this);


				if(dropBuilder!=null)
				{
					dropBuilder.buildIn( target,newNode );

					if(targetNode!=null)
					{
						DataLine line = new DataLine();
						line.replace( line.getEnd(),newNode.getTranslation().getPosition() );
						line.getColor().setValueT(50,this);
						targetNode.getShape().add(line,this);
					}
				}

				engine.getAPI().commit();
			}

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return true;
	}

	private DataNode findTarget( DataChildren children,GrfxMLEngine engine,DataPoint pointView )
	{
		for(int loop=0;loop<children.size();loop++)
		{
			DataNode node = children.get(loop);

			DataNode found = findTarget( node.getChildren(),engine,pointView );

			if(found!=null)
			{
				return found;
			}

			DataPoint point = new DataPoint();
			try{
				GrfxMLProcessor.reverseTranslate(pointView,TagModifier.POINT_TYPE_POINT,node.getTranslation(),point);
			}
			catch(Exception e)
			{
				continue;
			}

			DataShape shape = node.getShape();
			for(int loopS=0;loopS<shape.size();loopS++)
			{
				if( shape.get(loopS).getGeometry(engine).contains(point,pointView) )
				{
					return node;
				}
			}
		}

		return null;
	}

	private DropBuilder findDropBuilder(DataNode targetNode)
	{
		if(targetNode==null)
		{
			return null;
		}

		DropBuilder dropBuilder = null;

		DataProcess process = targetNode.getProcess();
		for(int loop=0;loop<process.size();loop++)
		{
			if(process.get(loop) instanceof DataActionPlugin)
			{
				DataActionPlugin actionPlugin = (DataActionPlugin)process.get(loop);

				if(actionPlugin.getPlugin() instanceof DropBuilder)
				{
					dropBuilder = (DropBuilder)actionPlugin.getPlugin();
				}
			}
		}

		if(dropBuilder==null)
		{
			dropBuilder = findDropBuilder( targetNode.getParent() );
		}

		return dropBuilder;
	}
}
